#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <android/log.h>
#include <stdbool.h>

#define LOGI(FORMATTER, ...) __android_log_print(ANDROID_LOG_INFO,"cherry_ndk_file",FORMATTER,__VA_ARGS__)
#define LOGE(FORMATTER, ...) __android_log_print(ANDROID_LOG_ERROR,"cherry_ndk_file",FORMATTER,__VA_ARGS__)

//获取文件大小
long get_file_size(char *path) {
    FILE *fp = fopen(path, "rb");
    fseek(fp, 0, SEEK_END);
    return ftell(fp);
}

JNIEXPORT jboolean JNICALL
Java_com_cherry_ndkdemo_FileSegmentMergeUtils_diff(
        JNIEnv *env, jclass jclz,
        jstring jpath, jstring jpath_pattern, jint jcount) {

    const char *path = (*env)->GetStringUTFChars(env, jpath, NULL);
    const char *path_pattern = (*env)->GetStringUTFChars(env, jpath_pattern, NULL);
    //需要分割的文件路径
    char **child_paths = malloc(sizeof(char *) * jcount);

    //设置并输出每个分割路径
    int i;
    for (i = 0; i < jcount; ++i) {
        child_paths[i] = malloc(sizeof(char) * 100);
        sprintf(child_paths[i], path_pattern, (i + 1));
        LOGI("分割文件路径=%s", child_paths[i]);
    }
    long file_size = get_file_size((char *) path);
    FILE *frp = fopen(path, "rb");
    if (file_size % jcount == 0) {
        int part = file_size / jcount;
        LOGI("开始分割，整除大小=%d", part);
        for (i = 0; i < jcount; ++i) {
            FILE *fwp = fopen(child_paths[i], "wb");
            for (int j = 0; j < part; ++j) {
                //边读边写
                fputc(fgetc(frp), fwp);
            }
            fclose(fwp);
        }
    } else {
        //先平均分割前面可以整除的
        int part = file_size / (jcount - 1);
        LOGI("开始分割，不能整除大小=%d", part);
        for (i = 0; i < jcount - 1; ++i) {
            FILE *fwp = fopen(child_paths[i], "wb");
            for (int j = 0; j < part; ++j) {
                //边读边写
                fputc(fgetc(frp), fwp);
            }
            fclose(fwp);
        }
        //再分割最后一个文件
        FILE *fwp = fopen(child_paths[jcount - 1], "wb");
        int last_part = file_size % (jcount - 1);
        for (int j = 0; j < last_part; ++j) {
            fputc(fgetc(frp), fwp);
        }
        fclose(fwp);
    }

    //释放资源
    fclose(frp);
    for (i = 0; i < jcount; ++i) {
        free(child_paths[i]);
    }
    free(child_paths);

    (*env)->ReleaseStringUTFChars(env, jpath, path);
    (*env)->ReleaseStringUTFChars(env, jpath_pattern, path_pattern);
    return true;
}

JNIEXPORT jboolean JNICALL
Java_com_cherry_ndkdemo_FileSegmentMergeUtils_patch(
        JNIEnv *env, jclass jclz,
        jstring jpath, jstring jpath_pattern, jint jcount) {

    const char *path = (*env)->GetStringUTFChars(env, jpath, NULL);
    const char *path_pattern = (*env)->GetStringUTFChars(env, jpath_pattern, NULL);

    char **child_paths = malloc(sizeof(char *) * jcount);
    int i;
    for (i = 0; i < jcount; ++i) {
        child_paths[i] = malloc(sizeof(char) * 100);
        sprintf(child_paths[i], path_pattern, (i + 1));
        LOGI("被分割的文件路径=%s", child_paths[i]);
    }

    FILE *fwp = fopen(path, "wb");
    for (i = 0; i < jcount; ++i) {
        FILE *frp = fopen(child_paths[i], "rb");
        long child_length = get_file_size(child_paths[i]);
        for (int j = 0; j < child_length; ++j) {
            fputc(fgetc(frp), fwp);
        }
        fclose(frp);
    }

    fclose(fwp);

    for (i = 0; i < jcount; ++i) {
        free(child_paths[i]);
    }
    free(child_paths);

    (*env)->ReleaseStringUTFChars(env, jpath, path);
    (*env)->ReleaseStringUTFChars(env, jpath_pattern, path_pattern);

    return true;
}
